/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
 *
 * Zhiqim Httpd is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.httpd;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;

import org.zhiqim.httpd.websocket.HttpWebSocketManager;
import org.zhiqim.kernel.config.Group;
import org.zhiqim.kernel.model.maps.HashMapSO;

/**
 * HTTP上下文环境接口定义
 *
 * @version v1.0.0 @author zouzhigang 2016-7-15 新建与整理
 */
public interface HttpContext
{
    /*********************************************************************/
    //创建 & 销毁
    /*********************************************************************/
    
    /** 上下文环境编号 */
    public String getId();
    
    /** 是否运行中 */
    public boolean isRunning();
    
    /** 资源是否在类路径中 */
    public boolean isClasspath();
    
    /** 创建 */
    public boolean create(Group group)throws Exception;
    
    /** 销毁 */
    public void destroy()throws Exception;
    
    /** 设置服务 */
    public void setServer(HttpServer server);
    
    /** 获取服务 */
    public HttpServer getServer();
    
    /** 获取上行最大内容长度 */
    public int getMaxContentLength();
    
    /** 获取设置的分块大小 */
    public int getChunkSize();
    
    /** 获取静态文件有效期 */
    public int getExpires();
    
    /** 判断是否是过滤的地址 */
    public boolean isFilterPath(String pathInContext);
    
    /** 获取匹配的处理器 */
    public HttpHandler getMatchHandler(String pathInContext);
    
    /**
     * 公共处理文件资源，该方法可以在匹配到的Handler中发现子匹配失败时回跳到文件资源处理中再检查一次
     * 
     * @param request           请求
     * @param response          响应
     * @exception HttpException HTTP异常
     * @exception IOException   IO异常
     */
    public void handleResource(HttpHeader header, HttpSender sender)throws HttpException, IOException;
    
    /** 
     * 默认处理请求，子类可以重写，默认查询Handler，如果查到对应由Handler处理，否则认为由ResourceHandler处理
     * 
     * @param request           请求
     * @param response          响应
     * @exception HttpException HTTP异常
     * @exception IOException   IO异常
     */
    public void handle(HttpRequest request, HttpResponse response)throws HttpException, IOException;
    
    /*********************************************************************/
    //上下文环境基本属性相关方法
    /*********************************************************************/
    
    /** 判断是否有上下文环境域名 */
    public HashSet<String> getContextDomains();
    
    /** 获取上下文环境路径 */
    public String getContextPath();
    
    /** 获取缺省编码 */
    public String getDefaultEncoding();
    
    /** 获取上下文环境资源路径 */
    public String getResourcePath();
    
    /** 获取上下文环境对应的真实路径 */
    public String getRealPath(String path);
    
    /** 获取上下文环境下绝对路径转为根环境下的绝对路径，如contextPath=/doc,path=/index.htm，得到/doc/index.htm */
    public String getRootPath(String path);
    
    /** 获取上下文环境欢迎页 */
    public String getWelcomeUrl();
    
    /** 获取上下文环境404页跳转页 */
    public String getNotFoundUrl();
    
    /** 获取上下文环境404页处理器 */
    public HttpEntity getNotFoundHandler();
    
    /** 获取OptionsHandler */
    public HttpEntity getOptionsHandler();
    
    /** 获取上下文环境会话管理器 */
    public HttpSessionManager getSessionManager();
    
    /** 设置指定的会话失效 */
    public void invalidateSession(String sessionId);
    
    /** 是否使用Cookie */
    public boolean isCookieUse();
    
    /** 获取使用Cookie时保存的域名 */
    public String getCookieDomain();
    
    /** 获取使用Cookie时保存的路径 */
    public String getCookiePath();
    
    /** 获取使用Cookie时保存的端口 */
    public int getCookiePort();
    
    /** 是否强制Cookie名称增加DomainPortPath前缀 */
    public boolean isCookieForce();
    
    /** 是否重定向 */
    public boolean isEncodeable();
    
    /**
     * 获取该资源内的资源字符串
     * 
     * @param path          请求
     * @return              =null表示不在该资源内,!=null表示在该资源内并读取到内容
     * @throws IOException  异常
     */
    public String getResourceString(String path) throws IOException;
    
    /**
     * 获取该资源内的资源字符串
     * 
     * @param path          请求
     * @param encoding      编码
     * @return              =null表示不在该资源内,!=null表示在该资源内并读取到内容
     * @throws IOException  异常
     */
    public String getResourceString(String path, String encoding) throws IOException;
    
    /**
     * 读取资源目录下的文件名和目录名，目录名以/结尾，用于显示目录下列表
     * 
     * @param folderPath    目录地址
     * @return              名称列表
     * @throws IOException  异常
     */
    public List<String> getResourceNameList(String folderPath) throws IOException;
    
    /*********************************************************************/
    //上下文环境自定义属性相关方法
    /*********************************************************************/
    
    /** 设置属性 */
    public void setAttribute(String key, Object value);
    
    /** 设置属性（通过类结构） */
    public <T> void setAttribute(Class<T> key, T value);
    
    /** 是否有该属性 */
    public boolean hasAttribute(String key);
    
    /** 获取属性表 */
    public HashMapSO getAttributes();
    
    /** 获取属性 */
    public Object getAttribute(String key);
    
    /** 获取上属性（通过类结构） */
    public <T> T getAttribute(Class<T> key);
    
    /** 获取属性，如果属性不存在则使用缺省值 */
    public Object getAttribute(String key, Object defaultValue);
    
    /** 获取上下文环境名称 */
    public String getContextName();
    
    /** 获取上下文环境版本 */
    public String getContextVersion();
    
    /** 获取字符串 */
    public String getAttributeString(String key);
    
    /** 获取字符串 ，如果属性不存在则使用缺省值*/
    public String getAttributeString(String key, String defaultValue);
    
    /** 获取整型 */
    public int getAttributeInt(String key);
    
    /** 获取整型 ，如果属性不存在则使用缺省值 */
    public int getAttributeInt(String key, int defaultValue);
    
    /** 获取长整型 */
    public long getAttributeLong(String key);
    
    /** 获取长整型 ，如果属性不存在则使用缺省值 */
    public long getAttributeLong(String key, long defaultValue);
    
    /** 获取布尔型 ，如果属性不存在则使用缺省值 */
    public boolean getAttributeBoolean(String key, boolean defaultValue);
    
    /*********************************************************************/
    //上下文环境WebSocket相关方法
    /*********************************************************************/
    
    /** 获取WebSocket管理器 */
    public HttpWebSocketManager getWebSocketManager();
}
